<?php
	$__ModelPools=array();
	
	class Model extends Table{
		
		
		/*var $__params=array();
		var $__expose_methods;
		var $__actionpath;*/
		var $_disable_lang;
		
		var $table=NULL;

		function Model($tablename=NULL){
			if(method_exists($this,"init")) $this->init();
			if($tablename!=NULL) $this->tablename=$tablename;
			$this->table=table($this->tablename);
		}
		
		function From($name,$params=NULL){
			
			global $__ModelPools;
			if(ereg("^[a-z]",$name)) {//is table name
				$tablename = $name;
				$classname = camelize($tablename)."Model";
				if(!isset($__ModelPools[$classname])){
					if(file_exists(($m_file=ROOT."/model/{$classname}.php"))){
						require_once($m_file);
						$__ModelPools[$classname]=new $classname($tablename);;
					}else{
						$__ModelPools[$classname]=new Model($tablename);
					}
				}
			}else{
				$classname = $name;
				if(!isset($__ModelPools[$classname])){
					
					if(file_exists(($m_file=$GLOBALS["system"]["controller_path"]."/model/{$classname}.php"))){
						require_once($m_file);
						//$__ModelPools[$classname]=&new $classname($tablename);
					}else{
						require_once(ROOT."/model/{$classname}.php");
					}
					$pairs=array();
					if(is_array($params)){
						foreach($params as $i=>$name){
							$pairs[]="\$params[$i]";
						}
					}
					eval("\$__ModelPools[\$classname] = &new ".$classname."(".implode(",",$pairs).");");
				}
				
			}	
			return $__ModelPools[$classname];
		}
		
		function SetLang($lang_table){
			$GLOBALS["Model"]["lang"] = $lang_table->current();
		}
		
		function GetLang(){
			$lang_code = $GLOBALS["Model"]["lang"];
			if($lang_code==DEF_LANG || !isset($lang_code)) return DEF_LANG;
			return $lang_code;
		}
		
		function select($colSql=NULL,$sqlcmds=NULL,$join=NULL){
			
			$map_cols = array();
			foreach(explode(',',$colSql) as $col){
				if(ereg("^@.*",$col)) $map_cols[]=substr($col,1);
			}
			
			//echo Model::GetLang();
			if(!$this->_disable_lang){
				if(Model::GetLang()!=DEF_LANG && $this->is_multi_lang){
					
					//echo $this->tablename."_lang_".Model::GetLang();
					$lang_table_name = ereg_replace("^".DB_PREFIX,"",$this->tablename)."_lang_".Model::GetLang();
					$lang_table = table($lang_table_name);
					
					//var_dump($lang_table->getColNames());lang_table
					if(trim($colSql)=="*") $colSql=array_diff($this->table->getColNames(),$lang_table->getColNamesWithoutPk());
					if(is_string($colSql)){
						$tmparr=array();
						foreach((explode(",",$colSql)) as $col){
							if(!in_array(trim($col),$lang_table->getColNamesWithoutPk())){
								$tmparr[]=$col;
							}
						}
						$colSql = implode(",",$tmparr);
					}
					
					
					if(is_array($colSql)){
						$colSql=array_diff($colSql,$lang_table->getColNamesWithoutPk());
					}
					
					$lefjoin = leftjoin($lang_table_name,implode(",",$lang_table->getColNamesWithoutPk()),"id=".current($lang_table->getPKNames()));
					if($join!=NULL){
						if(!empty($join["join"])){
							$join=array_merge($join,$lefjoin);
						}
					}else{
						$join=$lefjoin;
					}
					
					
					
				}
			}
			
			$rows =  $this->table->select($colSql,$sqlcmds,$join);
			
			if(count($rows)>0){
				foreach($map_cols as $col){
					//var_dump($this->map[$col]);
					
					if(isset($this->map[$col])){
						if(is_array($this->map[$col])){
							$mod = mod($this->map[$col][0]);
							$func = $this->map[$col][1];
							$rows=$mod->$func($col,$rows);
						}
						
						if(is_a($this->map[$col],"TableFieldMap")){
							$tfm = $this->map[$col];
							$func = $tfm->method;
							$tfm_r = $this->$func($col,$rows,$tfm->params);
							if($tfm_r!=NULL) $rows=$tfm_r;
						}
					}
					
				}
			}
			
			return $rows;
		}
		
		
		
		function count($condition=NULL){
			$this->_disable_lang=true;
			$r = $this->table->count($condition);
			$this->_disable_lang=false;
			return $r;
		}
		
		function getMaxArrange(){
			if(!isset($this->_max_arrange)){
				$this->_max_arrange=$this->table->selectOne("MAX(arrange)");
			}
			return $this->_max_arrange;
		}
		
		function getNextArrange(){
			return ($this->_max_arrange = $this->getMaxArrange()+1);
		}
		
		function insert($data){
			if($this->table->hasCol("arrange") && empty($data["arrange"])){
				$data["arrange"]=$this->getNextArrange();
			}
			return $this->table->insert($data);
		}
		
		function arrange($ids,$arrange_name="arrange",$direction="ASC"){
			
			$arranges = idAsKey($this->select("id,{$arrange_name}","WHERE id IN (".quote($ids).") ORDER BY {$arrange_name} {$direction},id {$direction}"));
			$index=0;
			$lasta=0;
			foreach($arranges as $id=>$a){
				if($a[$arrange_name]==$lasta){
					$arranges[$id][$arrange_name]=$a[$arrange_name]+($index++);
				}
				$lasta = $a[$arrange_name];
			}
			//trace(var_export($arranges,true));
			$rearrange = array_nlist($arrange_name,$arranges);
			foreach($ids as $i=>$id){
				$this->update(array("id"=>$id,$arrange_name=>$rearrange[$i]));
			}
		}
		
		function swapPublish($id,$pkanme="id"){
			
			if($this->hasCol("is_publish")){
				$id=intval($id);	
				$is_publish = $this->selectOne("is_publish","WHERE {$pkanme}='$id'")==1;
				$this->update(array($pkanme=>$id,"is_publish"=>intval(!$is_publish)));
				return !$is_publish;
			}
			
		}
		
		function save($data){
			$langcode = Model::GetLang();
			if($langcode==DEF_LANG){
				return $this->table->save($data);
			}
			
			if($this->is_multi_lang){
				//$langcode = strtolower($data['lang']);
				$lang_table = table(ereg_replace("^".DB_PREFIX,"",$this->tablename)."_lang_{$langcode}");
				$lang_table->_describe();
				
				$keyname = ereg_replace("^".DB_PREFIX,"",$this->tablename)."_id";
				
				foreach(array_diff(array_keys($lang_table->_cols) ,array($keyname)) as $col){
					if(isset($data[$col])){
						$lang_data[$col]=$data[$col];
					}
					unset($data[$col]);
				}
				
				$rid =  $this->table->save($data);
				
				$this->table->_describe();
				
				$lang_data[$keyname]=$rid ;
				$lang_table->replace($lang_data);
				
				return $rid;
			}
		}
		
		function update($data,$where=null){
			
			$langcode = Model::GetLang();
			if($langcode==DEF_LANG){
				return $this->table->update($data,$where);
			}
			
			if($this->is_multi_lang){
				$lang_table = table(ereg_replace("^".DB_PREFIX,"",$this->tablename)."_lang_{$langcode}");
				
				$lang_table->_describe();
				$keyname = ereg_replace("^".DB_PREFIX,"",$this->tablename)."_id";
				
				foreach(array_diff(array_keys($lang_table->_cols) ,array($keyname)) as $col){
					if(isset($data[$col])){
						$lang_data[$col]=$data[$col];
					}
					unset($data[$col]);
				}
				
				$r = $this->table->update($data,$where);
				
				unset($lang_data["id"]);
				$lang_table->update($lang_data,"WHERE {$keyname} = {$id}");
				
			}else{
				return $this->table->update($data,$where);
			}
			
			return $r;
			
		}
		
		function getImageSrc($id,$ext="jpg",$size=null){
			
			if(isset($size)){
				if(is_string($size)){
					$arr=explode("x",$size);
					$w=intval($arr[0]);
					$h=intval($arr[1]);
				}else{
					$w=$h=intval($size);
				}
				$sfile = pathjoin(ROOT,$this->image_path,"{$id}.{$ext}");
				
				if(!file_exists($sfile) || !is_file($sfile)){
					//return $this->getNoImageSrc($size);
				}
				
				if($size==0) return;
				if(!is_dir($dir=pathjoin(ROOT,$this->image_path,$size))){
					mkdir($dir);
				}
				$rfile = pathjoin($dir,"{$id}.{$ext}");
				
				if(!file_exists($rfile) || ( file_exists($rfile) && filectime($rfile)<=filectime($sfile))){
					require_once("core/Imager.php");
					$img = Imager::FromFile($sfile);
					$img->constrainIn($w,$h); 
					$img->save($rfile);
				}
				return pathjoin(BASE,ereg_replace("^".ROOT,"",$rfile));		
			}
			
			return pathjoin(BASE,$this->image_path,"{$id}.{$ext}");
		}
		
	}
	
?>